#! /bin/rwsh --init-file
.source /etc/rwshrc-basic $argv$

# only the fourth is needed, but this is the only test of these builtins
.toggle_readline
.toggle_readline
.disable_readline
.enable_readline

.try_catch_recursive .unused_variable {.collect_errors_except .nop {
  # set up environment
  fn set_if_undefined -- var [value] {
    .if .var_exists $var {.nop $value$}
    .else_if .var_exists value {.global $var $value}
    .else {.global $var ()}}
  set_if_undefined BUILT_EXECUTABLE /bin/rwsh
  set_if_undefined REGEX ()
  set_if_undefined grep-sel ()
  set_if_undefined s ()
  set_if_undefined s2 ()
  set_if_undefined FIGNORE .*
}}

# selection commands
fn sfn command {
  fn $command [-*] [file ...] {
    if_only .var_exists file {.selection_set s $file}
    &&{.which_path $command $PATH} $-*$ @$s}}
fn fn-subcommand system command {
  fn &&{c $system - $command} -- [args ...] {
    &&{whichp $system} &&command $args$}}
fn sfn-subcommand system command {
  fn &&{c $system - $command} [-*] [file ...] {
    if_only .var_exists file {.selection_set s $file}
    .if .test_not_empty $s {&&{whichp $system} &&command $-*$ @$s}
    .else {&&{whichp $system} &&command $-*$}}}
sfn cat 
fn cd [path] {
  if_only .var_exists path {.selection_set s $path}
  .cd @$s
  &{whichp pwd}
  .set s (); .set s2 ()}
fns chmod mode [file ...] {
  if_only .var_exists file {.selection_set s $file}
  &{whichp chmod} $-*$ $mode @$s}
fns cp dest {&{whichp cp} $-*$ @$s $dest}
fn create [file ...] {
  if_only .var_exists file {.selection_set s $file}
  &{whichp touch} $s$}
fns cvs command [file ...] {
  if_only .var_exists file {.selection_set s $file}
  .if .test_not_empty $s {&{whichp cvs} $-*$ $command @$s}
  .else {&{whichp cvs} $-*$ $command}}
fns darcs command [file ...] {
  if_only .var_exists file {.selection_set s $file}
  .if .test_not_empty $s {&{whichp darcs} $-*$ $command @$s}
  .else {&{whichp darcs} $-*$ $command}}
fns diff [one] [two] {
  # primary selection is _second_ operand, secondary selection is first
  if_only .var_exists two {.selection_set s $two}
  if_only .var_exists one {.selection_set s2 $one}
  &{whichp diff} $-*$ @$s2 @$s}
sfn du
fns ed [-p prompt] [file] {
  if_only .var_exists file {.selection_set s $file}
  &&{whichp ed} $-*$ @$s}
fns gdb-bash [binary] {
  if_only .var_exists binary {.set BUILT_EXECUTABLE $binary}
  echo debugging $BUILT_EXECUTABLE
  .scope /bin/bash SHELL {
    .nop $SHELL is for the environment
    &{whichp gdb} $-*$ $BUILT_EXECUTABLE}}
fns gdb [binary] {
  if_only .var_exists binary {.set BUILT_EXECUTABLE $binary}
  echo debugging $BUILT_EXECUTABLE
  &{whichp gdb} $-*$ $BUILT_EXECUTABLE}
fn git-git -- args ... {&{whichp git} $args$}
fns git command [file ...] {
  if_only .var_exists file {.selection_set s $file$}
  .if .test_not_empty $s {&{whichp git} $-*$ $command @$s}
  .else {&{whichp git} $-*$ $command}}
sfn-subcommand git add
fn-subcommand git branch
fn-subcommand git checkout
fn-subcommand git clone
fn-subcommand git config
sfn-subcommand git commit
sfn-subcommand git diff
fn-subcommand git fetch
fn-subcommand git help
fn-subcommand git log
fn-subcommand git merge
fn-subcommand git mv
fn-subcommand git remote
fn-subcommand git push
fn-subcommand git pull
fn-subcommand git rebase
sfn-subcommand git reset
sfn-subcommand git rm
fn-subcommand git show
sfn-subcommand git status
fns grep [-l] [regex] [file ...] {
  if_only .var_exists regex {.set REGEX $regex}
  if_only .var_exists file {.selection_set s $file}
  .try_catch_recursive .return_code {
    .if var_exists -l {
      .local_declare result
      .store_output result {&{whichp grep} $-*$ $REGEX @$s}
      .echo $result
      .set grep-sel $result$}
    .else {&{whichp grep} $-*$ $REGEX @$s}}}
fn grep-sel {.set s $grep-sel}
sfn gzip
sfn gunzip
fn home {cd $HOME}
fns head [-n lines] [-c bytes] [file ...] {
  if_only .var_exists file {.selection_set s $file}
  &&{whichp head} $-*$ @$s}
fn ignore args ... {.set FIGNORE $args$}
fns ll [file ...] {
  if_only .var_exists file {.selection_set s $file}
  &&{whichp ls} -ld $-*$ @$s}
fns ls [file ...] {
  if_only .var_exists file {.selection_set s $file}
  .if .test_not_empty $-* {&&{whichp ls} $-*$ @$s}
  .else {.ls @$s}}
sfn less 
sfn md5sum
fns mv dest {
  &{whichp mv} $-*$ @$s $dest
  .set s $dest}
fns regrep [file ...] {
  # wrap grep function to keep REGEX but change file
  .if .var_exists file {grep $-*$ $REGEX $file$}
  .else {grep $-*$}}
sfn rm 
sfn sum
fns tail [-b blocks] [-c bytes] [-n lines] [file ...] {
  if_only .var_exists file {.selection_set s $file}
  &&{whichp tail} $-*$ @$s}
fn tar bundled-flags [file ...] {
  if_only .var_exists file {.selection_set s $file}
  &{whichp tar} $bundled-flags @$s}
sfn touch
sfn vi 
sfn view
fns vim [file ...] {
  if_only .var_exists file {.selection_set s $file}
  .local old_shell $SHELL
  .set SHELL /bin/bash
  &{whichp vim} $-*$ @$s
  .set SHELL $old_shell}
sfn wc 
fn unselect {.set s ()}

# internal functions
fn .run_logic -- cmd [args ...] [.{argfunction}] {
   .try_catch_recursive &{.internal_functions}$ {$cmd $args$ {.argfunction}}
  # $* {.argfunction}}
fn .prompt {.echo $s; .echo \$}
fn .vars {
  .internal_vars
  echo $nl HOME $HOME
  echo REGEX $REGEX
  echo s $s}

# misc
fn . -- command ... {.source $command$}
fn ex_count -- cmd {.execution_count $cmd; c $nl}
fn exec -- command ... {.exec $command$ }
fn exit value {.exit $value}
fn last_time cmd {.last_execution_time $cmd; c $nl}
fn local {. &{c $HOME /.rwshrc}}
fn mark {ntimes 4 {.echo ####################}; c $nl}
fn timings cmd {
  .echo last time (); .last_execution_time $cmd; c $nl
  .echo total time (); .total_execution_time $cmd; c $nl
  .echo execution count (); .execution_count $cmd; c $nl}
fn total_time cmd {.total_execution_time $cmd; c $nl}
fn user_shell_ratio {
  .local time &&{.waiting_for_user}
  .var_divide time &&{.waiting_for_shell}
  .combine $time $nl}
fn waiting {
  echo for user ${.waiting_for_user}
  echo for binary ${.waiting_for_binary}
  echo for shell ${.waiting_for_shell}}
fn st-core [-?] [-nc] binary filter {
  if_only .var_exists -nc {.set -? $-?$ --suppress-common-lines}
  .collect_errors_except .nop {
    $binary -to <test_main.sh >last.test.result
    .if .test_not_empty $-? {
      &{whichp diff} $-?$ test.result last.test.result >last.test.result.diff}
    .else {
      &{whichp diff} -u test.result last.test.result >last.test.result.diff}
    $filter$ last.test.result.diff}}
fn mst [-?] {make; st $-*$}
fn to {./rwsh -to}
fn st [-?] {st-core $-*$ ./rwsh /bin/cat}
fn ist [-?] {st-core $-*$ /bin/rwsh /bin/cat}
fn st-diffstat [-?] {st-core $-*$ ./rwsh &{whichp diffstat}}
fn st-vis [-?] {st-core $-*$ ./rwsh (/bin/cat -A)}
fn bless-t {&{whichp cp} last.test.result test.result}
fn ti [-?] [-nc] {
  if_only .var_exists -nc {.set -? $-?$ --suppress-common-lines}
  .collect_errors_except .nop {
    to <test_inconsistent.sh >last.test_inconsistent.result
    &{whichp diff} $-?$ test_inconsistent.result last.test_inconsistent.result}}
fn ti-bless {/bin/cp last.test_inconsistent.result test_inconsistent.result}
fn mqt [-?] {make; qt $-*$}
fn qt [-?] [-nc] {
  if_only .var_exists -nc {.set -? $-?$ --suppress-common-lines}
  .collect_errors_except .nop {
    to <test_quick.sh >last.test_quick.result
    .if .test_not_empty $-? {
      &{whichp diff} $-?$ test_quick.result last.test_quick.result}
    .else {&{whichp diff} -u test_quick.result last.test_quick.result}}}
fn bless-qt {&{whichp cp} last.test_quick.result test_quick.result}
fn arg-out {./rwsh -to <argfunction.sh}
fn arg-diff [-?] {
  arg-out >argfunction.result.last
  .if .test_not_empty $-? {
    &{whichp diff} $-?$ argfunction.basic-result argfunction.result.last}
  .else {&{whichp diff} -u argfunction.basic-result argfunction.result.last}}
fn bless-arg {&{whichp cp} argfunction.result.last argfunction.basic-result}
fn counter {&{whichp rwsh} --init-file counter.rwsh}

# final setup and individual configuration
.source &{c $HOME /.rwshrc}
.if .var_exists already-initialized {.nop}
.else {
  .combine rwsh\ v &{.version} $nl
  .global already-initialized true}
if_only .var_exists argv {.error ignored excess arguments $argv $nl}
